/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.rpc.proxy;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.HeaderProvider2;
import com.alibaba.dubbo.common.header.HeaderProvider2Aware;
import com.alibaba.dubbo.common.utils.ReflectUtils;
import com.alibaba.dubbo.rpc.AsynInvoker;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.service.EchoService;

/**
 * AbstractProxyFactory
 * 
 * @author william.liangf
 */
public abstract class AbstractProxyFactory implements ProxyFactory {

	public <T> T getProxy(Invoker<T> invoker) throws RpcException {
		Class<?>[] interfaces = null;
		String config = invoker.getUrl().getParameter("interfaces");
		if (config != null && config.length() > 0) {
			String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
			if (types != null && types.length > 0) {
				// aruan 2014.09.09
				// aruan 2014.12.9 add AsyncInvoker
				interfaces = new Class<?>[types.length + 5];
				interfaces[0] = invoker.getInterface();
				interfaces[1] = HeaderProvider2.class;
				interfaces[2] = HeaderProvider2Aware.class;
				interfaces[3] = AsynInvoker.class;
				interfaces[4] = EchoService.class;
				for (int i = 0; i < types.length; i++) {
					interfaces[i + 5] = ReflectUtils.forName(types[i]);
				}
			}
		}
		if (interfaces == null) {
			interfaces = new Class<?>[] { invoker.getInterface(),
					HeaderProvider2.class, HeaderProvider2Aware.class, AsynInvoker.class,
					EchoService.class };
		}
		return getProxy(invoker, interfaces);
	}

	public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types);

}